home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™94
/
Talks & Papers
/
Michael D. Crawford↵
/
Word Services SDK 1.0.5
/
Writeswell Jr. Source
/
Prefs.c
< prev
next >
Wrap
Text File
|
1992-12-29
|
13KB
|
668 lines
/* Prefs.c
* Preferences file management
* ©1992 Working Software, Inc.
* This source code is copyrighted. Permission is granted to use the Word Services
* portion of the Writeswell Jr. source code in your own programs, but you
* may not distribute the Writeswell Jr. word-processor code as a
* commercial product. If you modify the code, please do not call it
* Writeswell Jr. (or Writeswell.) This will ensure that people understand the
* program and don’t have to deal with a number of different versions with
* who-knows-what going on in the code.
*
* Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
* 18 Apr 92 Mike Crawford
*/
#include <EPPC.h>
#include <AppleEvents.h>
#include <AEObjects.h>
#include <Folders.h>
#include <Aliases.h>
#include "AERegistry.h"
#include "TBConstants.h"
#include "TBGlobals.h"
#include "Prefs.h"
#include "MyGestalt.h"
#include "MyFolders.h"
#include "Gripe.h"
#define kAFServiceBaseID 2000
#define kAFMenuIconBaseID 1257
Boolean OpenPrefFile( void )
{
short oldDrive;
long oldDir;
OSErr err;
short vRef;
long dirID;
WDParam wPB;
short curFile;
Str255 prefsFileName;
/* Find the preferences folder */
if ( GetPrefFolder( &vRef, &dirID ) )
return false;
/* Check if file exists */
GetIndString( prefsFileName, kMiscStringID, kPreferencesFileNameStr );
if ( prefsFileName[0] == '\0' )
return false;
if ( !FileExistsWithThisType( vRef, dirID, prefsFileName, 'pref' ) ){
/* if not, create it with default prefs */
if ( !CreateDefaultPrefFile( vRef, dirID, prefsFileName ) )
return false;
}
/* otherwise, open the file */
wPB.ioCompletion = 0;
wPB.ioNamePtr = (StringPtr)NULL;
err = PBHGetVol( &wPB, false );
if ( err )
return false;
oldDrive = wPB.ioWDVRefNum;
oldDir = wPB.ioWDDirID;
wPB.ioVRefNum = vRef;
wPB.ioWDDirID = dirID;
wPB.ioNamePtr = (StringPtr)NULL;
err = PBHSetVol( &wPB, false );
if ( err )
return false;
curFile = CurResFile();
gPrefFileRefNum = OpenResFile( prefsFileName );
err = ResError();
UseResFile( curFile ); /* Restore old res file */
wPB.ioVRefNum = oldDrive;
wPB.ioWDDirID = oldDir;
err = PBHSetVol( &wPB, false ); /* Restore original volume */
if ( gPrefFileRefNum == -1 || err ){
return false;
}
if ( ValidatePrefsFile() )
return false;
return true;
}
OSErr ValidatePrefsFile( void )
{
short curFile;
short i;
OSErr err;
Handle h;
curFile = CurResFile();
UseResFile( gPrefFileRefNum );
/* Get defaults out of the application */
if ( !( h = Get1Resource( 'PreF', kPFPrefsID )) ){
if ( err = CopyResource( kAFPrefsID, kPFPrefsID, 'PreF', gAppFileRefNum, gPrefFileRefNum )){
UseResFile( curFile );
return err;
}
#ifdef __DEMO__
/* Pre-install Spellswell in the menu
* 1.0.2 MDC I put this inside the if Get1Resource statement
*/
if ( System7Installed() ){
if ( err = AddSpellerItem() ){
UseResFile( curFile );
return err;
}
}
#endif
}
UpdateResFile( gPrefFileRefNum );
UseResFile( curFile );
err = ResError();
return err;
}
#ifdef __DEMO__
OSErr AddSpellerItem( void )
{
OSErr err;
FSSpec spellerSpec;
Boolean foundSpeller;
Handle h;
WWJrPrefsHdl prefHdl;
/* We want to show the menu already installed for the demo disks */
if ( err = LookForSpeller( &spellerSpec, &foundSpeller ) )
return err;
if ( !foundSpeller )
return noErr; /* No error - speller was just not there */
if ( !( h = Get1Resource( rAliasType, kServiceBaseID )) )
if ( err = CopyResource( kAFServiceBaseID, kServiceBaseID, rAliasType, gAppFileRefNum, gPrefFileRefNum )){
return err;
}
if ( err = PointAliasAtSpeller( kServiceBaseID, &spellerSpec ) ){
return err;
}
if ( !( h = Get1Resource( 'STR ', kServiceBaseID )) )
if ( err = CopyResource( kAFServiceBaseID, kServiceBaseID, 'STR ', gAppFileRefNum, gPrefFileRefNum )){
return err;
}
if ( !( h = Get1Resource( 'SICN', kMenuIconBaseID )) )
if ( err = CopyResource( kAFMenuIconBaseID, kMenuIconBaseID, 'SICN', gAppFileRefNum, gPrefFileRefNum )){
return err;
}
prefHdl = GetPrefHandle();
if ( !prefHdl ){
Gripe( "\pCannot get preferences handle" );
return resNotFound;
}
(*prefHdl)->serviceType[ 0 ] = kBatchService;
ChangedResource( prefHdl );
WriteResource( prefHdl );
return noErr;
}
OSErr LookForSpeller( FSSpec *spellSpecPtr, Boolean *foundPtr )
{
OSErr err;
short vRef;
long dirID;
CInfoPBRec cPB;
Str255 fileName;
short dirIndex;
*foundPtr = false;
err = GetMyFolder( &vRef, &dirID );
if ( err )
return err;
/* Now we search for the speller by creator code and type, by indexing through
* the folder's contents.
*/
dirIndex = 0;
do {
dirIndex++;
cPB.hFileInfo.ioCompletion = (ProcPtr)NULL;
cPB.hFileInfo.ioNamePtr = fileName;
cPB.hFileInfo.ioVRefNum = vRef;
cPB.hFileInfo.ioFDirIndex = dirIndex;
cPB.hFileInfo.ioDirID = dirID;
err = PBGetCatInfo( &cPB, false );
if ( err && err != fnfErr )
return err;
if ( cPB.dirInfo.ioFlAttrib & 0x10 )
continue; /* It's a directory */
if ( cPB.hFileInfo.ioFlFndrInfo.fdType == 'APPL' ){
if ( cPB.hFileInfo.ioFlFndrInfo.fdCreator == 'SPWE' ){
/* We've got the speller. Create the FSSpec for it */
err = FSMakeFSSpec( vRef,
dirID,
fileName,
spellSpecPtr );
if ( !err )
*foundPtr = true;
return err;
}
}
} while ( err != fnfErr );
/* If we get here, then the speller is simply not present */
return noErr;
}
OSErr GetMyFolder( short *vRefPtr, long *dirIDPtr )
{
Handle codeHdl;
short appRefNum;
FCBPBRec pb;
FSSpec fSpec;
OSErr err;
Str255 fileName;
/* Find out our resource file refNum */
codeHdl = GetResource( 'CODE', 0 ); /* Get a resource from our res file */
if ( !codeHdl )
return resNotFound;
appRefNum = HomeResFile( codeHdl );
pb.ioCompletion = (ProcPtr)NULL;
pb.ioRefNum = appRefNum;
pb.ioVRefNum = 0;
pb.ioFCBIndx = 0;
pb.ioNamePtr = fileName;
err = PBGetFCBInfo( &pb, false );
if ( err ){
Gripe( "\pGetFCBInfo failed" );
return err;
}
*vRefPtr = pb.ioVRefNum;
*dirIDPtr = pb.ioFCBParID;
return noErr;
}
OSErr PointAliasAtSpeller( short aliasID, const FSSpecPtr spellerSpecPtr )
{
OSErr err;
AliasHandle oldAliasHdl;
Boolean wasChanged;
/* Get an existing alias from the preferences file, and "aim" it at
* Spellswell 7, which is given by the spellerSpecPtr.
* This allows the demo to be run off of locked demo disks and CD's, without
* having to set up the alias record ahead of time.
*/
oldAliasHdl = (AliasHandle)GetResource( rAliasType, aliasID );
if ( !oldAliasHdl )
return resNotFound;
err = UpdateAlias( (FSSpecPtr)NULL, spellerSpecPtr, oldAliasHdl, &wasChanged );
if ( err ){
Gripe( "\pUpdateAlias failed" );
return err;
}
(*oldAliasHdl)->userType = 'SPWE'; /* Put creator into alias record */
ChangedResource( oldAliasHdl );
WriteResource( oldAliasHdl );
return noErr;
}
#endif
OSErr GetPrefFolder( short *vRefPtr, long *dirIDPtr )
{
OSErr errCode;
long blessedID;
if ( FindFolderPresent() ){
errCode = FindFolder( kOnSystemDisk,
kPreferencesFolderType,
true,
vRefPtr,
dirIDPtr );
return errCode;
}
/* System 6 style */
/* First, get the refNum of the boot drive, and the ID of the system folder */
errCode = GetSysVolID( vRefPtr, &blessedID );
if ( errCode ){
return errCode;
}
/* Now get the ID of the "Preferences" folder in the system folder.
* if it does not exist, create it. */
errCode = FindDirectory( *vRefPtr, blessedID, "\pPreferences", dirIDPtr );
if ( errCode == dirNFErr ){
errCode = MakeFolder( dirIDPtr, *vRefPtr, blessedID, "\pPreferences" );
if ( errCode )
return errCode;
} else if ( errCode ){
return errCode;
}
return noErr;
}
Boolean FileExistsWithThisType( short vRef, long dirID, StringPtr fileName, OSType type )
{
OSErr err;
HParmBlkPtr pbPtr;
Boolean result;
long oldSize;
pbPtr = (HParmBlkPtr)NewPtr( sizeof( HParamBlockRec ) );
if ( !pbPtr )
return false;
pbPtr->fileParam.ioCompletion = (ProcPtr)NULL;
pbPtr->fileParam.ioDirID = dirID;
pbPtr->fileParam.ioNamePtr = fileName;
pbPtr->fileParam.ioVRefNum = vRef;
pbPtr->fileParam.ioFDirIndex = 0;
err = PBHGetFInfo( pbPtr, false );
if ( err ){
result = false;
} else {
if ( pbPtr->fileParam.ioFlFndrInfo.fdType != type )
result = false;
else
result = true;
}
DisposPtr( pbPtr );
return result;
}
Boolean CreateDefaultPrefFile( short vRef, long dirID, StringPtr fileName )
{
OSErr err;
HParmBlkPtr pbPtr;
Boolean result;
short wdRef;
long oldDir;
short oldVol;
long oldSize;
/* We cannot count on the presence of HCreateResFile */
pbPtr = (HParmBlkPtr)NewPtr( sizeof( HParamBlockRec ) );
if ( !pbPtr )
return false;
pbPtr->wdParam.ioCompletion = (ProcPtr)NULL;
pbPtr->wdParam.ioWDDirID = dirID;
pbPtr->wdParam.ioNamePtr = (StringPtr)NULL;
pbPtr->wdParam.ioVRefNum = vRef;
pbPtr->wdParam.ioWDProcID = 'ERIK';
err = PBOpenWD( pbPtr, false );
if ( err ){
DisposPtr( pbPtr );
return false;
}
wdRef = pbPtr->wdParam.ioVRefNum;
pbPtr->wdParam.ioCompletion = (ProcPtr)NULL;
err = PBHGetVol( pbPtr, false );
if ( err ){
DisposPtr( pbPtr );
return false;
}
oldDir = pbPtr->wdParam.ioWDDirID;
oldVol = pbPtr->wdParam.ioWDVRefNum;
((ParmBlkPtr)pbPtr)->fileParam.ioCompletion = (ProcPtr)NULL;
((ParmBlkPtr)pbPtr)->fileParam.ioNamePtr = (StringPtr)NULL;
((ParmBlkPtr)pbPtr)->fileParam.ioVRefNum = wdRef;
err = PBSetVol( pbPtr, false );
if ( err ){
DisposPtr( pbPtr );
return false;
}
CreateResFile( fileName );
err = ResError();
if ( err ){
DisposPtr( pbPtr );
return false;
}
pbPtr->fileParam.ioCompletion = (ProcPtr)NULL;
pbPtr->fileParam.ioDirID = dirID;
pbPtr->fileParam.ioNamePtr = fileName;
pbPtr->fileParam.ioVRefNum = vRef;
pbPtr->fileParam.ioFDirIndex = 0;
err = PBHGetFInfo( pbPtr, false );
if ( err ){
DisposPtr( pbPtr );
return false;
}
pbPtr->fileParam.ioFlFndrInfo.fdType = 'pref';
pbPtr->fileParam.ioFlFndrInfo.fdCreator = 'MiKe';
pbPtr->fileParam.ioDirID = dirID;
pbPtr->fileParam.ioNamePtr = fileName;
pbPtr->fileParam.ioVRefNum = vRef;
pbPtr->fileParam.ioFDirIndex = 0;
err = PBHSetFInfo( pbPtr, false );
if ( err ){
DisposPtr( pbPtr );
return false;
}
pbPtr->wdParam.ioCompletion = (ProcPtr)NULL;
pbPtr->wdParam.ioWDDirID = oldDir;
pbPtr->wdParam.ioNamePtr = (StringPtr)NULL;
pbPtr->wdParam.ioVRefNum = oldVol;
err = PBHSetVol( pbPtr, false );
if ( err ){
DisposPtr( pbPtr );
return false;
}
pbPtr->wdParam.ioCompletion = (ProcPtr)NULL;
pbPtr->wdParam.ioVRefNum = wdRef;
err = PBCloseWD( pbPtr, false );
DisposPtr( pbPtr );
if ( err )
return false;
return true;
}
OSErr CopyResource( short fromID,
short toID,
ResType theType,
short fromFile,
short toFile )
{
short curFile;
Handle h;
Str255 name;
short attr;
ResType myType;
short myID;
OSErr err;
/* This function will not work correctly if the ChangedResource
* or purge bits are set.
*/
curFile = CurResFile();
UseResFile( fromFile );
if ( err = ResError() ){
return err;
}
h = GetResource( theType, fromID );
UseResFile( curFile );
if ( err || (err = ResError()) ){
return err;
}
if ( !h || !*h ){
return resNotFound;
}
GetResInfo( h, &myID, &myType, name );
if ( err = ResError() ){
return err;
}
attr = GetResAttrs( h );
if ( err = ResError() ){
return err;
}
DetachResource( h );
if ( err = ResError() ){
return err;
}
curFile = CurResFile();
UseResFile( toFile );
AddResource( h, theType, toID, name );
if ( err = ResError() ){
UseResFile( curFile );
return err;
}
WriteResource( h );
if ( err = ResError() ){
UseResFile( curFile );
return err;
}
UseResFile( curFile );
if ( err = ResError() ){
return err;
}
SetResAttrs( h, attr );
if ( err = ResError() ){
return err;
}
return noErr;
}
#ifdef NEVER /* This will return in a future version */
void ToggleSelectCheck( void )
{
WWJrPrefsHdl prefHdl;
prefHdl = GetPrefHandle();
if ( !prefHdl ){
Gripe( "\pCannot get preferences handle" );
return;
}
if ( (*prefHdl)->checkSel ){
(*prefHdl)->checkSel = 0;
}else{
(*prefHdl)->checkSel = 1;
}
ChangedResource( prefHdl );
WriteResource( prefHdl );
CheckSelectMenu( prefHdl );
return;
}
void CheckSelectMenu( WWJrPrefsHdl prefHdl )
{
MenuHandle servMenu;
servMenu = GetServiceMenu();
if ( !servMenu ){
Gripe( "\pCannot get service menu handle" );
return;
}
if ( (*prefHdl)->checkSel ){
CheckItem( servMenu, kSMCheckSel, true );
}else{
CheckItem( servMenu, kSMCheckSel, false );
}
return;
}
#endif
MenuHandle GetServiceMenu( void )
{
MenuHandle servMenu;
servMenu = (MenuHandle)GetResource( 'MENU', kServMenuID );
return servMenu;
}
WWJrPrefsHdl GetPrefHandle( void )
{
WWJrPrefsHdl prefHdl;
short curFile;
curFile = CurResFile();
UseResFile( gPrefFileRefNum );
prefHdl = (WWJrPrefsHdl)GetResource( 'PreF', kPFPrefsID );
UseResFile( curFile );
return prefHdl; /* Might be Nil; up to caller to check */
}